use crate::types::NodeType;
use eframe::egui::{Context, Id, Rect};
use std::sync::{Arc, Mutex, Weak};

pub type ANode = Arc<Mutex<Node>>;
pub type WNode = Weak<Mutex<Node>>;

static mut NEXT_NODE_ID: u32 = 0;
pub struct Node {
    pub id: u32,
    // 父节点
    pub parent: Option<WNode>,
    // 子节点
    pub children: Vec<ANode>,
    // 关联节点
    pub relate: Option<ANode>,
    // 关联父节点
    pub relate_parent: Option<WNode>,
    // 标题
    pub title: NodeAttr<String>,
    // 参数
    pub params: NodeAttr<String>,
    // 节点类型
    pub node_type: NodeAttr<NodeType>,
    // 矩形
    pub rect: Rect,
    // 是否折叠
    pub is_expand: bool,
}

#[derive(Default)]
pub struct NodeAttr<T> {
    pub title: String,
    pub tips: String,
    pub value: T
}

impl <T> NodeAttr<T> {
    pub fn new(title: &str, tips: &str, value: T) -> Self {
        Self {
            title: title.to_string(),
            tips: tips.to_string(),
            value,
        }
    }
}

impl Default for Node {
    fn default() -> Self {
        unsafe {
            NEXT_NODE_ID += 1;
            Node {
                id: NEXT_NODE_ID,
                parent: None,
                children: vec![],
                relate: None,
                relate_parent: None,
                title: NodeAttr::new("节点名称", "", "".to_string()),
                params: NodeAttr::new("节点参数", "", "".to_string()),
                node_type: NodeType::Composite(false, false).into(),
                rect: Rect::ZERO,
                is_expand: false,
            }
        }
    }
}

impl From<Node> for ANode {
    fn from(val: Node) -> Self {
        Arc::new(Mutex::new(val))
    }
}

impl Node {
    pub fn new() -> Node {
        Self::default()
    }
    pub fn with_title(mut self, title: String) -> Node {
        self.title.value = title;
        self
    }

    fn curr_id() -> Id {
        Id::new("current_node")
    }

    fn root_id() -> Id {
        Id::new("root_node")
    }

    fn list_root_id() -> Id {
        Id::new("list_root_node")
    }

    pub fn get_current_node(ctx: &Context) -> ANode {
        ctx.data(|data| {
            data.get_temp(Self::curr_id()).unwrap()
        })
    }

    pub fn set_current_node(ctx: &Context, node: ANode) {
        ctx.data_mut(|data| {
            data.insert_temp(Self::curr_id(), node);
        });
    }

    // 获取根节点
    pub fn get_root_node(ctx: &Context) -> ANode {
        ctx.data(|data| {
            data.get_temp(Self::root_id()).unwrap()
        })
    }

    pub fn set_root_node(ctx: &Context, node: ANode) {
        ctx.data_mut(|data| {
            data.insert_temp(Self::root_id(), node);
        });
    }

    // 获取根节点
    pub fn get_list_root_node(ctx: &Context) -> ANode {
        ctx.data(|data| {
            data.get_temp(Self::list_root_id()).unwrap()
        })
    }

    pub fn set_list_root_node(ctx: &Context, node: ANode) {
        ctx.data_mut(|data| {
            data.insert_temp(Self::list_root_id(), node);
        });
    }

    /**
    *
    * @return parent, relate, children, brother
    */
    pub fn get_nodes(node: &ANode) -> (Option<ANode>, Option<ANode>, Vec<ANode>, Vec<ANode>) {
        let mut parent_node = None;
        let mut relate_node = None;
        let mut children = vec![];
        let mut brother = vec![];
        let node_guard = node.lock().unwrap();
        match &node_guard.relate {
            None => {}
            Some(relate) => {
                relate_node = Some(Arc::clone(relate));
            }
        };
        match &node_guard.relate_parent {
            None => {}
            Some(relate) => {
                match relate.upgrade() {
                    None => {}
                    Some(relate) => {
                        relate_node = Some(Arc::clone(&relate));
                    }
                };
            }
        };

        match &node_guard.parent {
            None => {}
            Some(parent) => {
                match parent.upgrade() {
                    None => {}
                    Some(parent) => {
                        parent_node = Some(Arc::clone(&parent));
                        let parent_guard = parent.lock().unwrap();
                        for x in &parent_guard.children {
                            // 跳过当前节点，当前节点已绘制，不需要在兄弟节点上绘制
                            // 上面已经获取了node的锁，这里获取会失败，因为rust mutex不支持可重入锁
                            if x.try_lock().is_err() { continue; };
                            brother.push(Arc::clone(x));
                        };
                    }
                };
            }
        };
        for x in &node_guard.children {
            children.push(Arc::clone(x));
        };
        (parent_node, relate_node, children, brother)
    }
}
